package com.zshan.clinic.common.util.attack;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;


/**
 * SQL注入
 */
@Slf4j
public class SqlCleanUtil {


    /**
     * sql注入
     * @param params
     * @return
     */
    public static boolean inject(Map<String, Object> params){
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            Object value = entry.getValue();
            if (value instanceof List) {
                if (!injectList((List<Object>) value)) {
                    return false;
                }
            } else if (value instanceof Map) {
                if (!inject((Map<String, Object>) value)) {
                    return false;
                }
            } else {
                if (value != null) {
                    String strVal = String.valueOf(value);
                    if (!"".equals(strVal) && !"null".equalsIgnoreCase(strVal)) {
                        if (!sqlInject(strVal)) {
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }

    private static boolean injectList(List<Object> list) {
        for (Object value : list) {
            if (value instanceof List) {
                if (!injectList((List<Object>) value)) {
                    return false;
                }
            } else if (value instanceof Map) {
                if (!inject((Map<String, Object>) value)) {
                    return false;
                }
            } else {
                if (value != null) {
                    String strVal = String.valueOf(value);
                    if (!"".equals(strVal) && !"null".equalsIgnoreCase(strVal)) {
                        if (!sqlInject(strVal)) {
                            return false;
                        }
                    }
                }
            }
        }
        return true;
    }

    public static boolean sqlInject(String str) {
        if (StringUtils.isBlank(str)) {
            return true;
        }

        // 转小写，替换掉空格等分隔符，防止绕过
        String lowerStr = str.toLowerCase().replaceAll("[\\s\\t\\n\\r]+", " ");

        String[] keywords = {
                "truncate", "insert", "select", "delete", "update",
                "declare", "alert", "create", "drop"
        };

        for (String keyword : keywords) {
            if (lowerStr.contains(keyword)) {
                return false;
            }
        }
        return true;
    }


    /**
     * SQL注入过滤
     *
     * @param arr 待验证的字符串
     */
    public static String hasKeyword(String... arr) {
        if (arr == null || arr.length == 0) {
            return null;
        }

        // 非法字符
        String[] keywords = {"master", "truncate", "insert", "select", "delete", "update", "declare", "alert",
                "create", "drop"};
        for (String item : arr) {
            // 判断是否包含非法字符
            for (String keyword : keywords) {
                if (item.trim().toLowerCase().contains(keyword)) {
                    log.info("包含非法字符{}", keyword);
                    return keyword;
                }
            }
        }
        return null;
    }
}
